import json
import os
import random
from typing import Dict, List, Optional, Tuple

class RustCodeChallenge:
    """Rust代码闯关游戏，用于通过拖拽代码卡片学习Rust难点"""
    
    def __init__(self):
        """初始化代码闯关游戏"""
        self.challenges_file = "challenge_data/challenges.json"
        self.progress_file = "challenge_data/user_progress.json"
        
        # 确保目录存在
        os.makedirs(os.path.dirname(self.challenges_file), exist_ok=True)
        os.makedirs(os.path.dirname(self.progress_file), exist_ok=True)
        
        # 初始化挑战数据
        self._init_challenges()
        
        # 初始化用户进度
        self._init_progress()
    
    def _init_challenges(self):
        """初始化挑战数据"""
        # 如果文件已存在，不覆盖
        if os.path.exists(self.challenges_file):
            return
            
        challenges = {
            "topics": {
                "所有权": {
                    "name": "所有权(Ownership)",
                    "description": "学习Rust的所有权系统，理解内存管理的基本原理",
                    "challenges": [
                        {
                            "id": "ownership_1",
                            "title": "理解所有权转移",
                            "difficulty": "简单",
                            "description": "将代码片段拖拽到正确位置，完成所有权转移的示例",
                            "template": "fn main() {\n    let s1 = String::from(\"hello\");\n    <dropzone id=\"1\"></dropzone>;\n    // s1 在这里已经不再有效\n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let s2 = s1", "code": "let s2 = s1"},
                                {"id": "println!(\"{}\", s2)", "code": "println!(\"{}\", s2)"}
                            ],
                            "solution": {
                                "1": "let s2 = s1",
                                "2": "println!(\"{}\", s2)"
                            },
                            "explanation": "在Rust中，当您将一个变量赋值给另一个变量时，所有权会从第一个变量转移到第二个变量。"
                        },
                        {
                            "id": "ownership_2",
                            "title": "理解克隆",
                            "difficulty": "简单",
                            "description": "使用clone()方法创建数据的深拷贝",
                            "template": "fn main() {\n    let s1 = String::from(\"hello\");\n    <dropzone id=\"1\"></dropzone>;\n    <dropzone id=\"2\"></dropzone>;\n    <dropzone id=\"3\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let s2 = s1.clone()", "code": "let s2 = s1.clone()"},
                                {"id": "println!(\"s1 = {}, s2 = {}\", s1, s2)", "code": "println!(\"s1 = {}, s2 = {}\", s1, s2)"},
                                {"id": "// s1 仍然有效", "code": "// s1 仍然有效"}
                            ],
                            "solution": {
                                "1": "let s2 = s1.clone()",
                                "2": "// s1 仍然有效",
                                "3": "println!(\"s1 = {}, s2 = {}\", s1, s2)"
                            },
                            "explanation": "使用clone()方法可以创建数据的深拷贝，这样原始变量仍然有效。"
                        }
                    ]
                },
                "借用检查器": {
                    "name": "借用检查器(Borrowing)",
                    "description": "学习Rust的借用规则，理解引用的概念",
                    "challenges": [
                        {
                            "id": "borrowing_1",
                            "title": "不可变引用",
                            "difficulty": "简单",
                            "description": "使用不可变引用访问数据而不获取所有权",
                            "template": "fn main() {\n    let s1 = String::from(\"hello\");\n    <dropzone id=\"1\"></dropzone>;\n    <dropzone id=\"2\"></dropzone>;\n    <dropzone id=\"3\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let len = calculate_length(&s1)", "code": "let len = calculate_length(&s1)"},
                                {"id": "println!(\"'{}' 的长度是 {}。\", s1, len)", "code": "println!(\"'{}' 的长度是 {}。\", s1, len)"},
                                {"id": "fn calculate_length(s: &String) -> usize { s.len() }", "code": "fn calculate_length(s: &String) -> usize { s.len() }"}
                            ],
                            "solution": {
                                "1": "fn calculate_length(s: &String) -> usize { s.len() }",
                                "2": "let len = calculate_length(&s1)",
                                "3": "println!(\"'{}' 的长度是 {}。\", s1, len)"
                            },
                            "explanation": "使用&符号创建引用，可以在不获取所有权的情况下访问数据。"
                        },
                        {
                            "id": "borrowing_2",
                            "title": "可变引用",
                            "difficulty": "中等",
                            "description": "使用可变引用修改数据",
                            "template": "fn main() {\n    <dropzone id=\"1\"></dropzone>;\n    <dropzone id=\"2\"></dropzone>;\n    <dropzone id=\"3\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let mut s = String::from(\"hello\")", "code": "let mut s = String::from(\"hello\")"},
                                {"id": "change(&mut s)", "code": "change(&mut s)"},
                                {"id": "fn change(some_string: &mut String) { some_string.push_str(\", world\"); }", "code": "fn change(some_string: &mut String) { some_string.push_str(\", world\"); }"}
                            ],
                            "solution": {
                                "1": "let mut s = String::from(\"hello\")",
                                "2": "fn change(some_string: &mut String) { some_string.push_str(\", world\"); }",
                                "3": "change(&mut s)"
                            },
                            "explanation": "使用&mut创建可变引用，可以修改数据。注意变量必须声明为mut。"
                        }
                    ]
                },
                "生命周期": {
                    "name": "生命周期(Lifetimes)",
                    "description": "学习Rust的生命周期概念，理解引用的有效性",
                    "challenges": [
                        {
                            "id": "lifetime_1",
                            "title": "函数生命周期",
                            "difficulty": "困难",
                            "description": "为函数添加生命周期参数",
                            "template": "<dropzone id=\"1\"></dropzone> {\n    <dropzone id=\"2\"></dropzone>\n}\n\nfn main() {\n    let string1 = String::from(\"长字符串\");\n    let string2 = \"xyz\";\n    let result = longest(&string1, string2);\n    println!(\"最长的字符串是 {}\", result);\n}",
                            "snippets": [
                                {"id": "fn longest<'a>(x: &'a str, y: &'a str) -> &'a str", "code": "fn longest<'a>(x: &'a str, y: &'a str) -> &'a str"},
                                {"id": "if x.len() > y.len() { x } else { y }", "code": "if x.len() > y.len() { x } else { y }"}
                            ],
                            "solution": {
                                "1": "fn longest<'a>(x: &'a str, y: &'a str) -> &'a str",
                                "2": "if x.len() > y.len() { x } else { y }"
                            },
                            "explanation": "生命周期参数<'a>确保返回的引用在传入的引用都有效时也有效。"
                        }
                    ]
                },
                "Trait系统": {
                    "name": "Trait系统(Traits)",
                    "description": "学习Rust的特征系统，定义共享行为",
                    "challenges": [
                        {
                            "id": "trait_1",
                            "title": "定义和实现特征",
                            "difficulty": "中等",
                            "description": "定义特征并为类型实现它",
                            "template": "<dropzone id=\"1\"></dropzone>;\n\n<dropzone id=\"2\"></dropzone>;\n\n<dropzone id=\"3\"></dropzone>;\n\nfn main() {\n    let article = NewsArticle {\n        headline: String::from(\"Penguins win the Stanley Cup Championship!\"),\n        location: String::from(\"Pittsburgh, PA, USA\"),\n        author: String::from(\"Iceburgh\"),\n        content: String::from(\"The Pittsburgh Penguins once again are the best hockey team in the NHL.\"),\n    };\n    \n    println!(\"New article available! {}\", article.summarize());\n}",
                            "snippets": [
                                {"id": "pub trait Summary {\n    fn summarize(&self) -> String;\n}", "code": "pub trait Summary {\n    fn summarize(&self) -> String;\n}"},
                                {"id": "pub struct NewsArticle {\n    pub headline: String,\n    pub location: String,\n    pub author: String,\n    pub content: String,\n}", "code": "pub struct NewsArticle {\n    pub headline: String,\n    pub location: String,\n    pub author: String,\n    pub content: String,\n}"},
                                {"id": "impl Summary for NewsArticle {\n    fn summarize(&self) -> String {\n        format!(\"{}, by {} ({})\", self.headline, self.author, self.location)\n    }\n}", "code": "impl Summary for NewsArticle {\n    fn summarize(&self) -> String {\n        format!(\"{}, by {} ({})\", self.headline, self.author, self.location)\n    }\n}"}
                            ],
                            "solution": {
                                "1": "pub trait Summary {\n    fn summarize(&self) -> String;\n};",
                                "2": "pub struct NewsArticle {\n    pub headline: String,\n    pub location: String,\n    pub author: String,\n    pub content: String,\n};",
                                "3": "impl Summary for NewsArticle {\n    fn summarize(&self) -> String {\n        format!(\"{}, by {} ({})\", self.headline, self.author, self.location)\n    }\n}"
                            },
                            "explanation": "特征定义了共享行为，类型可以实现特征来获得特定功能。"
                        }
                    ]
                },
                "闭包": {
                    "name": "闭包(Closures)",
                    "description": "学习Rust的闭包，可以捕获环境的匿名函数",
                    "challenges": [
                        {
                            "id": "closure_1",
                            "title": "基本闭包使用",
                            "difficulty": "简单",
                            "description": "使用闭包创建简短的匿名函数",
                            "template": "fn main() {\n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n    \n    <dropzone id=\"3\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let add_one = |x| x + 1", "code": "let add_one = |x| x + 1"},
                                {"id": "let five = 5", "code": "let five = 5"},
                                {"id": "println!(\"5 + 1 = {}\", add_one(five))", "code": "println!(\"5 + 1 = {}\", add_one(five))"}
                            ],
                            "solution": {
                                "1": "let five = 5",
                                "2": "let add_one = |x| x + 1",
                                "3": "println!(\"5 + 1 = {}\", add_one(five))"
                            },
                            "explanation": "闭包是匿名函数，可以捕获其环境中的变量。使用|参数| 表达式语法定义。"
                        },
                        {
                            "id": "closure_2",
                            "title": "闭包捕获环境",
                            "difficulty": "中等",
                            "description": "闭包捕获外部环境中的变量",
                            "template": "fn main() {\n    let x = 4;\n    \n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let equal_to_x = |z| z == x", "code": "let equal_to_x = |z| z == x"},
                                {"id": "let y = 4", "code": "let y = 4"},
                                {"id": "assert!(equal_to_x(y))", "code": "assert!(equal_to_x(y))"}
                            ],
                            "solution": {
                                "1": "let equal_to_x = |z| z == x",
                                "2": "let y = 4",
                                "3": "assert!(equal_to_x(y))"
                            },
                            "explanation": "闭包可以捕获其定义环境中的变量，即使这些变量不在闭包的参数列表中。"
                        }
                    ]
                },
                "并发": {
                    "name": "并发(Concurrency)",
                    "description": "学习Rust的并发编程，安全地编写多线程代码",
                    "challenges": [
                        {
                            "id": "concurrency_1",
                            "title": "创建线程",
                            "difficulty": "中等",
                            "description": "使用std::thread创建和管理线程",
                            "template": "use std::thread;\nuse std::time::Duration;\n\nfn main() {\n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n    \n    <dropzone id=\"3\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let handle = thread::spawn(|| {", "code": "let handle = thread::spawn(|| {"},
                                {"id": "for i in 1..10 {", "code": "for i in 1..10 {"},
                                {"id": "println!(\"hi number {} from the spawned thread!\", i);", "code": "println!(\"hi number {} from the spawned thread!\", i);"},
                                {"id": "thread::sleep(Duration::from_millis(1));", "code": "thread::sleep(Duration::from_millis(1));"},
                                {"id": "}", "code": "}"},
                                {"id": "});", "code": "});"},
                                {"id": "handle.join().unwrap();", "code": "handle.join().unwrap();"}
                            ],
                            "solution": {
                                "1": "let handle = thread::spawn(|| {",
                                "2": "for i in 1..10 {",
                                "3": "println!(\"hi number {} from the spawned thread!\", i);",
                                "4": "thread::sleep(Duration::from_millis(1));",
                                "5": "}",
                                "6": "});",
                                "7": "handle.join().unwrap();"
                            },
                            "explanation": "使用thread::spawn创建新线程，返回JoinHandle。调用join()等待线程完成。"
                        }
                    ]
                },
                "宏": {
                    "name": "宏(Macros)",
                    "description": "学习Rust的宏系统，编写在编译时生成代码的元编程",
                    "challenges": [
                        {
                            "id": "macro_1",
                            "title": "使用println!宏",
                            "difficulty": "简单",
                            "description": "使用println!宏格式化输出",
                            "template": "fn main() {\n    let name = \"Alice\";\n    let age = 30;\n    \n    <dropzone id=\"1\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "println!(\"{} is {} years old.\", name, age)", "code": "println!(\"{} is {} years old.\", name, age)"}
                            ],
                            "solution": {
                                "1": "println!(\"{} is {} years old.\", name, age)"
                            },
                            "explanation": "println!是Rust中最常用的宏之一，用于格式化输出到控制台。"
                        },
                        {
                            "id": "macro_2",
                            "title": "使用vec!宏",
                            "difficulty": "简单",
                            "description": "使用vec!宏创建向量",
                            "template": "fn main() {\n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let v = vec![1, 2, 3, 4, 5]", "code": "let v = vec![1, 2, 3, 4, 5]"},
                                {"id": "println!(\"Vector: {:?}\", v)", "code": "println!(\"Vector: {:?}\", v)"}
                            ],
                            "solution": {
                                "1": "let v = vec![1, 2, 3, 4, 5]",
                                "2": "println!(\"Vector: {:?}\", v)"
                            },
                            "explanation": "vec!宏简化了向量的创建，可以直接用方括号列出初始元素。"
                        }
                    ]
                },
                "模式匹配": {
                    "name": "模式匹配(Pattern Matching)",
                    "description": "学习Rust的match表达式和模式，处理不同的情况",
                    "challenges": [
                        {
                            "id": "pattern_1",
                            "title": "基本match表达式",
                            "difficulty": "简单",
                            "description": "使用match表达式处理不同的值",
                            "template": "fn main() {\n    let number = 13;\n    \n    <dropzone id=\"1\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "println!(\"Tell me about {}\", number);", "code": "println!(\"Tell me about {}\", number);"},
                                {"id": "match number {", "code": "match number {"},
                                {"id": "1 => println!(\"One!\"),", "code": "1 => println!(\"One!\"),"},
                                {"id": "2 | 3 | 5 | 7 | 11 => println!(\"This is a prime\"),", "code": "2 | 3 | 5 | 7 | 11 => println!(\"This is a prime\"),"},
                                {"id": "13..=19 => println!(\"A teen\"),", "code": "13..=19 => println!(\"A teen\"),"},
                                {"id": "_ => println!(\"Ain't special\"),", "code": "_ => println!(\"Ain't special\"),"},
                                {"id": "}", "code": "}"}
                            ],
                            "solution": {
                                "1": "println!(\"Tell me about {}\", number);",
                                "2": "match number {",
                                "3": "1 => println!(\"One!\"),",
                                "4": "2 | 3 | 5 | 7 | 11 => println!(\"This is a prime\"),",
                                "5": "13..=19 => println!(\"A teen\"),",
                                "6": "_ => println!(\"Ain't special\"),",
                                "7": "}"
                            },
                            "explanation": "match表达式允许将一个值与一系列模式进行比较，并执行匹配的模式对应的代码。"
                        }
                    ]
                },
                "迭代器": {
                    "name": "迭代器(Iterators)",
                    "description": "学习Rust的迭代器，处理序列数据",
                    "challenges": [
                        {
                            "id": "iterator_1",
                            "title": "使用迭代器",
                            "difficulty": "简单",
                            "description": "使用迭代器处理集合",
                            "template": "fn main() {\n    let v = vec![1, 2, 3];\n    \n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let v_iter = v.iter()", "code": "let v_iter = v.iter()"},
                                {"id": "for val in v_iter {", "code": "for val in v_iter {"},
                                {"id": "println!(\"Got: {}\", val);", "code": "println!(\"Got: {}\", val);"},
                                {"id": "}", "code": "}"}
                            ],
                            "solution": {
                                "1": "let v_iter = v.iter()",
                                "2": "for val in v_iter {",
                                "3": "println!(\"Got: {}\", val);",
                                "4": "}"
                            },
                            "explanation": "迭代器允许处理一个序列中的每个元素。iter()方法创建一个不可变引用的迭代器。"
                        },
                        {
                            "id": "iterator_2",
                            "title": "迭代器适配器",
                            "difficulty": "中等",
                            "description": "使用迭代器适配器链式处理数据",
                            "template": "fn main() {\n    let v1 = vec![1, 2, 3];n    \n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let v2: Vec<_> = v1.iter().map(|x| x + 1).collect()", "code": "let v2: Vec<_> = v1.iter().map(|x| x + 1).collect()"},
                                {"id": "println!(\"{:?}\", v2);", "code": "println!(\"{:?}\", v2);"}
                            ],
                            "solution": {
                                "1": "let v2: Vec<_> = v1.iter().map(|x| x + 1).collect()",
                                "2": "println!(\"{:?}\", v2);"
                            },
                            "explanation": "迭代器适配器如map、filter等可以对迭代器进行转换，collect()将结果收集到集合中。"
                        }
                    ]
                },
                "错误处理": {
                    "name": "错误处理(Error Handling)",
                    "description": "学习Rust的错误处理机制，使用Result和Option",
                    "challenges": [
                        {
                            "id": "error_1",
                            "title": "使用Result",
                            "difficulty": "中等",
                            "description": "使用Result类型处理可能失败的操作",
                            "template": "use std::fs::File;\n\nfn main() {\n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let f = File::open(\"hello.txt\")", "code": "let f = File::open(\"hello.txt\")"},
                                {"id": "let f = match f {\n    Ok(file) => file,\n    Err(error) => panic!(\"打开文件出错: {:?}\", error),\n};", "code": "let f = match f {\n    Ok(file) => file,\n    Err(error) => panic!(\"打开文件出错: {:?}\", error),\n};"}
                            ],
                            "solution": {
                                "1": "let f = File::open(\"hello.txt\")",
                                "2": "let f = match f {\n    Ok(file) => file,\n    Err(error) => panic!(\"打开文件出错: {:?}\", error),\n};"
                            },
                            "explanation": "Result类型用于可能失败的操作，包含Ok(成功)和Err(错误)两种情况。"
                        },
                        {
                            "id": "error_2",
                            "title": "使用Option",
                            "difficulty": "简单",
                            "description": "使用Option类型处理可能不存在的值",
                            "template": "fn main() {\n    <dropzone id=\"1\"></dropzone>;\n    \n    <dropzone id=\"2\"></dropzone>;\n}",
                            "snippets": [
                                {"id": "let some_number = Some(5)", "code": "let some_number = Some(5)"},
                                {"id": "let some_number = match some_number {\n    Some(i) => i,\n    None => 0,\n};", "code": "let some_number = match some_number {\n    Some(i) => i,\n    None => 0,\n};"}
                            ],
                            "solution": {
                                "1": "let some_number = Some(5)",
                                "2": "let some_number = match some_number {\n    Some(i) => i,\n    None => 0,\n};"
                            },
                            "explanation": "Option类型用于可能不存在的值，包含Some(值)和None两种情况。"
                        }
                    ]
                }
            }
        }
        
        with open(self.challenges_file, 'w', encoding='utf-8') as f:
            json.dump(challenges, f, ensure_ascii=False, indent=2)
    
    def _init_progress(self):
        """初始化用户进度"""
        # 如果文件已存在，不覆盖
        if os.path.exists(self.progress_file):
            return
            
        progress = {
            "user_id": "default_user",
            "unlocked_topics": ["所有权"],
            "completed_challenges": {},
            "current_challenge": {
                "topic": "所有权",
                "challenge_id": "ownership_1"
            }
        }
        
        with open(self.progress_file, 'w', encoding='utf-8') as f:
            json.dump(progress, f, ensure_ascii=False, indent=2)
    
    def get_challenges(self) -> Dict:
        """获取所有挑战数据"""
        with open(self.challenges_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    
    def get_progress(self) -> Dict:
        """获取用户进度"""
        with open(self.progress_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    
    def update_progress(self, progress: Dict):
        """更新用户进度"""
        with open(self.progress_file, 'w', encoding='utf-8') as f:
            json.dump(progress, f, ensure_ascii=False, indent=2)
    
    def get_topic_challenges(self, topic_key: str) -> List[Dict]:
        """
        获取特定主题的挑战列表
        
        Args:
            topic_key: 主题键名
            
        Returns:
            挑战列表
        """
        challenges = self.get_challenges()
        return challenges["topics"].get(topic_key, {}).get("challenges", [])
    
    def get_challenge(self, topic_key: str, challenge_id: str) -> Optional[Dict]:
        """
        获取特定挑战
        
        Args:
            topic_key: 主题键名
            challenge_id: 挑战ID
            
        Returns:
            挑战数据
        """
        challenges = self.get_topic_challenges(topic_key)
        for challenge in challenges:
            if challenge["id"] == challenge_id:
                return challenge
        return None
    
    def check_solution(self, topic_key: str, challenge_id: str, user_solution: Dict) -> Dict:
        """
        检查用户解决方案
        
        Args:
            topic_key: 主题键名
            challenge_id: 挑战ID
            user_solution: 用户解决方案
            
        Returns:
            检查结果
        """
        challenge = self.get_challenge(topic_key, challenge_id)
        if not challenge:
            return {"success": False, "message": "挑战不存在"}
        
        correct_solution = challenge["solution"]
        
        # 检查解决方案
        is_correct = True
        incorrect_zones = []
        
        for zone_id, expected_snippet_id in correct_solution.items():
            if zone_id not in user_solution or user_solution[zone_id] != expected_snippet_id:
                is_correct = False
                incorrect_zones.append(zone_id)
        
        # 如果解决方案正确，更新进度
        if is_correct:
            progress = self.get_progress()
            
            # 标记挑战为已完成
            if topic_key not in progress["completed_challenges"]:
                progress["completed_challenges"][topic_key] = []
            
            if challenge_id not in progress["completed_challenges"][topic_key]:
                progress["completed_challenges"][topic_key].append(challenge_id)
            
            # 检查是否解锁新主题
            challenges = self.get_challenges()
            topic_challenges = challenges["topics"][topic_key]["challenges"]
            
            # 如果当前主题的所有挑战都完成，解锁下一个主题
            if len(progress["completed_challenges"][topic_key]) == len(topic_challenges):
                topic_keys = list(challenges["topics"].keys())
                current_index = topic_keys.index(topic_key)
                
                if current_index < len(topic_keys) - 1:
                    next_topic = topic_keys[current_index + 1]
                    if next_topic not in progress["unlocked_topics"]:
                        progress["unlocked_topics"].append(next_topic)
            
            # 更新当前挑战
            topic_challenges = self.get_topic_challenges(topic_key)
            current_index = next((i for i, c in enumerate(topic_challenges) if c["id"] == challenge_id), None)
            
            if current_index is not None and current_index < len(topic_challenges) - 1:
                progress["current_challenge"] = {
                    "topic": topic_key,
                    "challenge_id": topic_challenges[current_index + 1]["id"]
                }
            
            self.update_progress(progress)
            
            return {
                "success": True,
                "message": "恭喜！你完成了这个挑战！",
                "explanation": challenge["explanation"],
                "unlocked_topics": progress["unlocked_topics"]
            }
        else:
            return {
                "success": False,
                "message": "还有一些代码片段没有放到正确的位置。",
                "incorrect_zones": incorrect_zones
            }
    
    def get_unlocked_topics(self) -> List[str]:
        """获取已解锁的主题"""
        progress = self.get_progress()
        return progress["unlocked_topics"]
    
    def get_current_challenge(self) -> Dict:
        """获取当前挑战"""
        progress = self.get_progress()
        current = progress["current_challenge"]
        return self.get_challenge(current["topic"], current["challenge_id"])
    
    def set_current_challenge(self, topic_key: str, challenge_id: str):
        """设置当前挑战"""
        progress = self.get_progress()
        progress["current_challenge"] = {
            "topic": topic_key,
            "challenge_id": challenge_id
        }
        self.update_progress(progress)